Much
of the SQL Server Profiler functionality can also be initiated through a
set of system stored procedures. Through these procedures, you can
define a server-side trace that can be run automatically or on a
scheduled basis, such as via a scheduled job, instead of through the
Profiler GUI. Server-side traces are also useful if you are tracing
information over an extended period of time or are planning on capturing
a large amount of trace information. The overhead of running a
server-side trace is less than that of running a client-side trace with
Profiler.
To
start a server-side trace, you need to define the trace by using the
trace-related system procedures. These procedures can be called from
within a SQL Server stored procedure or batch. You define a server-side
trace by using the following four procedures:
sp_trace_create— This procedure is used to create the trace definition. It sets up the trace and defines the file to store the captured events. sp trace create returns a trace ID number that you need to reference from the other three procedures to further define and manage the trace.
sp_trace_setevent— You need to call this procedure once for each data column of every event that you want to capture.
sp_trace_setfilter— You call this procedure once for each filter you want to define on an event data column.
sp_trace_setstatus—
After the trace is defined, you call this procedure to start, stop, or
remove the trace. You must stop and remove a trace definition before you
can open and view the trace file.
You will find that
manually creating procedure scripts for tracing can be rather tedious.
Much of the tedium is due to the fact that many numeric parameters drive
the trace execution. For example, the sp_trace_setevent procedure accepts an eventid and a columnid
that determine what event data will be captured. Fortunately, SQL
Server 2008 provides a set of catalog views that contain these numeric
values and what they represent. The sys.trace_categories catalog view contains the event categories. The sys.trace_events catalog view contains the trace events, and sys.trace_columns contains the trace columns. The following SELECT statement utilizes two of these system views to return the available events and their related categories:
select e.trace_event_id, e.name 'Event Name', c.name 'Category Name'
from sys.trace_events e
join sys.trace_categories c on e.category_id = c.category_id
order by e.trace_event_id
The results of this SELECT statement are shown in Table 1.
Table 1. Trace Events and Their Related Categories
trace_event_id | Event Name | Category Name |
---|
10 | RPC:Completed | Stored Procedures |
11 | RPC:Starting | Stored Procedures |
12 | SQL:BatchCompleted | T-SQL |
13 | SQL:BatchStarting | T-SQL |
14 | Audit Login | Security Audit |
15 | Audit Logout | Security Audit |
16 | Attention | Errors and Warnings |
17 | ExistingConnection | Sessions |
18 | Audit Server Starts And Stops | Security Audit |
19 | DTCTransaction | Transactions |
20 | Audit Login Failed | Security Audit |
21 | EventLog | Errors and Warnings |
22 | ErrorLog | Errors and Warnings |
23 | Lock:Released | Locks |
24 | Lock:Acquired | Locks |
25 | Lock:Deadlock | Locks |
26 | Lock:Cancel | Locks |
27 | Lock:Timeout | Locks |
28 | Degree of Parallelism | Performance |
33 | Exception | Errors and Warnings |
34 | SP:CacheMiss | Stored Procedures |
35 | SP:CacheInsert | Stored Procedures |
36 | SP:CacheRemove | Stored Procedures |
37 | SP:Recompile | Stored Procedures |
38 | SP:CacheHit | Stored Procedures |
40 | SQL:StmtStarting | T-SQL |
41 | SQL:StmtCompleted | T-SQL |
42 | SP:Starting | Stored Procedures |
43 | SP:Completed | Stored Procedures |
44 | SP:StmtStarting | Stored Procedures |
45 | SP:StmtCompleted | Stored Procedures |
46 | Object:Created | Objects |
47 | Object:Deleted | Objects |
50 | SQLTransaction | Transactions |
51 | Scan:Started | Scans |
52 | Scan:Stopped | Scans |
53 | CursorOpen | Cursors |
54 | TransactionLog | Transactions |
55 | Hash Warning | Errors and Warnings |
58 | Auto Stats | Performance |
59 | Lock:Deadlock Chain | Locks |
60 | Lock:Escalation | Locks |
61 | OLEDB Errors | OLEDB |
67 | Execution Warnings | Errors and Warnings |
68 | Showplan Text (Unencoded) | Performance |
69 | Sort Warnings | Errors and Warnings |
70 | CursorPrepare | Cursors |
71 | Prepare SQL | T-SQL |
72 | Exec Prepared SQL | T-SQL |
73 | Unprepare SQL | T-SQL |
74 | CursorExecute | Cursors |
75 | CursorRecompile | Cursors |
76 | CursorImplicitConversion | Cursors |
77 | CursorUnprepare | Cursors |
78 | CursorClose | Cursors |
79 | Missing Column Statistics | Errors and Warnings |
80 | Missing Join Predicate | Errors and Warnings |
81 | Server Memory Change | Server |
82 | UserConfigurable:0 | User configurable |
83 | UserConfigurable:1 | User configurable |
84 | UserConfigurable:2 | User configurable |
85 | UserConfigurable:3 | User configurable |
86 | UserConfigurable:4 | User configurable |
87 | UserConfigurable:5 | User configurable |
88 | UserConfigurable:6 | User configurable |
89 | UserConfigurable:7 | User configurable |
90 | UserConfigurable:8 | User configurable |
91 | UserConfigurable:9 | User configurable |
92 | Data File Auto Grow | Database |
93 | Log File Auto Grow | Database |
94 | Data File Auto Shrink | Database |
95 | Log File Auto Shrink | Database |
96 | Showplan Text | Performance |
97 | Showplan All | Performance |
98 | Showplan Statistics Profile | Performance |
100 | RPC Output Parameter | Stored Procedures |
102 | Audit Database Scope GDR Event | Security Audit |
103 | Audit Schema Object GDR Event | Security Audit |
104 | Audit Addlogin Event | Security Audit |
105 | Audit Login GDR Event | Security Audit |
106 | Audit Login Change Property Event | Security Audit |
107 | Audit Login Change Password Event | Security Audit |
108 | Audit Add Login to Server Role Event | Security Audit |
109 | Audit Add DB User Event | Security Audit |
110 | Audit Add Member to DB Role Event | Security Audit |
111 | Audit Add Role Event | Security Audit |
112 | Audit App Role Change Password Event | Security Audit |
113 | Audit Statement Permission Event | Security Audit |
114 | Audit Schema Object Access Event | Security Audit |
115 | Audit Backup/Restore Event | Security Audit |
116 | Audit DBCC Event | Security Audit |
117 | Audit Change Audit Event | Security Audit |
118 | Audit Object Derived Permission Event | Security Audit |
119 | OLEDB Call Event | OLEDB |
120 | OLEDB QueryInterface Event | OLEDB |
121 | OLEDB DataRead Event | OLEDB |
122 | Showplan XML | Performance |
123 | SQL:FullTextQuery | Performance |
124 | Broker:Conversation | Broker |
125 | Deprecation Announcement | Deprecation |
126 | Deprecation Final Support | Deprecation |
127 | Exchange Spill Event | Errors and Warnings |
128 | Audit Database Management Event | Security Audit |
129 | Audit Database Object Management Event | Security Audit |
130 | Audit Database Principal Management Event | Security Audit |
131 | Audit Schema Object Management Event | Security Audit |
132 | Audit Server Principal Impersonation Event | Security Audit |
133 | Audit Database Principal Impersonation Event | Security Audit |
134 | Audit Server Object Take Ownership Event | Security Audit |
135 | Audit Database Object Take Ownership Event | Security Audit |
136 | Broker:Conversation Group | Broker |
137 | Blocked process report | Errors and Warnings |
138 | Broker:Connection | Broker |
139 | Broker:Forwarded Message Sent | Broker |
140 | Broker:Forwarded Message Dropped | Broker |
141 | Broker:Message Classify | Broker |
142 | Broker:Transmission | Broker |
143 | Broker:Queue Disabled | Broker |
144 | Broker:Mirrored Route State Changed | Broker |
146 | Showplan XML Statistics Profile | Performance |
148 | Deadlock graph | Locks |
149 | Broker:Remote Message Acknowledgement | Broker |
150 | Trace File Close | Server |
151 | Database Mirroring Connection | Database |
152 | Audit Change Database Owner | Security Audit |
153 | Audit Schema Object Take Ownership Event | Security Audit |
154 | Audit Database Mirroring Login | Security Audit |
155 | FT:Crawl Started | Full text |
156 | FT:Crawl Stopped | Full text |
157 | FT:Crawl Aborted | Full text |
158 | Audit Broker Conversation | Security Audit |
186 | TM: Commit Tran completed | Transactions |
187 | TM: Rollback Tran starting | Transactions |
188 | TM: Rollback Tran completed | Transactions |
189 | Lock:Timeout (timeout > 0) | Locks |
190 | Progress Report: Online Index Operation | Progress Report |
191 | TM: Save Tran starting | Transactions |
192 | TM: Save Tran completed | Transactions |
193 | Background Job Error | Errors and Warnings |
194 | OLEDB Provider Information | OLEDB |
195 | Mount Tape | Server |
196 | Assembly Load | CLR |
198 | XQuery Static Type | T-SQL |
199 | QN: Subscription | Query Notifications |
200 | QN: Parameter table | Query Notifications |
201 | QN: Template | Query Notifications |
202 | QN: Dynamics | Query Notifications |
212 | Bitmap Warning | Errors and Warnings |
213 | Database Suspect Data Page | Errors and Warnings |
214 | CPU threshold exceeded | Errors and Warnings |
215 | PreConnect:Starting | Sessions |
216 | PreConnect:Completed | Sessions |
217 | Plan Guide Successful | Performance |
218 | Plan Guide Unsuccessful | Performance |
235 | Audit Fulltext | Security Audit |
The numeric IDs for the trace columns can be obtained from the sys.trace_columns catalog view, as shown in the following example:
select trace_column_id, name 'Column Name', type_name 'Data Type'
from sys.trace_columns
order by trace_column_id
Table 2 shows the results of this SELECT statement and lists all the available trace columns.
Table 2. Trace Columns Available for a Server-Side Trace
trace_column_id | Column Name | Data Type |
---|
1 | TextData | text |
2 | BinaryData | image |
3 | DatabaseID | int |
4 | TransactionID | bigint |
5 | LineNumber | int |
6 | NTUserName | nvarchar |
7 | NTDomainName | nvarchar |
8 | HostName | nvarchar |
9 | ClientProcessID | int |
10 | ApplicationName | nvarchar |
11 | LoginName | nvarchar |
12 | SPID | int |
13 | Duration | bigint |
14 | StartTime | datetime |
15 | EndTime | datetime |
16 | Reads | bigint |
17 | Writes | bigint |
18 | CPU | int |
19 | Permissions | bigint |
20 | Severity | int |
21 | EventSubClass | int |
22 | ObjectID | int |
23 | Success | int |
24 | IndexID | int |
25 | IntegerData | int |
26 | ServerName | nvarchar |
27 | EventClass | int |
28 | ObjectType | int |
29 | NestLevel | int |
30 | State | int |
31 | Error | int |
32 | Mode | int |
33 | Handle | int |
34 | ObjectName | nvarchar |
35 | DatabaseName | nvarchar |
36 | FileName | nvarchar |
37 | OwnerName | nvarchar |
38 | RoleName | nvarchar |
39 | TargetUserName | nvarchar |
40 | DBUserName | nvarchar |
41 | LoginSid | image |
42 | TargetLoginName | nvarchar |
43 | TargetLoginSid | image |
44 | ColumnPermissions | int |
45 | LinkedServerName | nvarchar |
46 | ProviderName | nvarchar |
47 | MethodName | nvarchar |
48 | RowCounts | bigint |
49 | RequestID | int |
50 | XactSequence | bigint |
51 | EventSequence | bigint |
52 | BigintData1 | bigint |
53 | BigintData2 | bigint |
54 | GUID | uniqueidentifier |
55 | IntegerData2 | int |
56 | ObjectID2 | bigint |
57 | Type | int |
58 | OwnerID | int |
59 | ParentName | nvarchar |
60 | IsSystem | int |
61 | Offset | int |
62 | SourceDatabaseID | int |
63 | SqlHandle | image |
64 | SessionLoginName | nvarchar |
65 | PlanHandle | image |
66 | GroupID | int |
You have to call the sp_trace_setevent
procedure once for each data column you want captured for each event in
the trace. Based on the number of events and number of columns, you can
see that this can result in a lot of executions of the sp_trace_setevent procedure for a larger trace definition.
To set up filters, you must
pass the column ID, the filter value, and numeric values for the logical
operator and column operator to the sp_trace_setfilter procedure. The logical operator can be either 0 or 1. A value of 0 indicates that the specified filter on the column should be ANDed with any other filters on the column, whereas a value of 1 indicates that the OR operator should be applied. Table 3 describes the values allowed for the column operators.
Table 3. Column Operator Values for sp_trace_setfilter
Value | Comparison Operator |
---|
0 | = (equal) |
1 | <> (not equal) |
2 | > (greater than) |
3 | < (less than) |
4 | >= (greater than or equal) |
5 | <= (less than or equal) |
6 | LIKE |
7 | NOT LIKE |
Fortunately, there is
an easier way of generating a trace definition script. You can set up
your traces by using the SQL Profiler GUI and script the trace
definition to a file. After you define the trace and specify the events,
data columns, and filters you want to use, you select File, Export,
Script Trace Definition. The SQL commands (including calls to the
aforementioned system stored procedures) to define the trace, start the
trace, and write the trace to a file are generated into one script file.
You have the option to generate a script that works with SQL Server
2000, 2005 or 2008. Listing 1 shows an example of a trace definition exported from the Profiler. It contains the trace definitions for the TSQL trace template. You must replace the text InsertFileNameHere with an appropriate filename, prefixed with its pathname, before running this script.
Listing 1. A SQL Script for Creating and Starting a Server-Side Trace
/****************************************************/ /* Created by: SQL Server 2008 Profiler */ /* Date: 05/10/2009 07:20:54 PM */ /****************************************************/
-- Create a Queue declare @rc int declare @TraceID int declare @maxfilesize bigint set @maxfilesize = 5
— Please replace the text InsertFileNameHere, with an appropriate — filename prefixed by a path, e.g., c:\MyFolder\MyTrace. The .trc extension — will be appended to the filename automatically. If you are writing from — remote server to local drive, please use UNC path and make sure server has — write access to your network share
exec @rc = sp_trace_create @TraceID output, 0, N'InsertFileNameHere', @maxfilesize, NULL if (@rc != 0) goto error
— Client side File and Table cannot be scripted
— Set the events declare @on bit set @on = 1 exec sp_trace_setevent @TraceID, 10, 2, @on exec sp_trace_setevent @TraceID, 10, 12, @on exec sp_trace_setevent @TraceID, 10, 13, @on exec sp_trace_setevent @TraceID, 12, 1, @on exec sp_trace_setevent @TraceID, 12, 12, @on exec sp_trace_setevent @TraceID, 12, 13, @on
— Set the Filters declare @intfilter int declare @bigintfilter bigint
— Set the trace status to start exec sp_trace_setstatus @TraceID, 1
— display trace id for future references select TraceID=@TraceID goto finish
error: select ErrorCode=@rc finish:
go
|
Tip
If you want to always capture certain trace events when SQL Server is
running, such as auditing events, you can create a stored procedure that
uses the sp_trace stored procedures to create a trace and specify the events to be captured. You can use the code in Listing 1 as a basis to create the stored procedure. Then you can mark the procedure as a startup procedure by using the sp_procoption procedure to set the autostart option. The trace automatically starts when SQL Server is started, and it continues running in the background.
Just be aware that
although using server-side traces is less intrusive than using the SQL
Profiler client, some overhead is necessary to run a trace. You should
try to limit the number of events and number of columns captured to
minimize the overhead as much as possible.
Monitoring Running Traces
SQL Server 2008
provides some additional built-in user-defined functions to get
information about currently running traces. Like the fn_trace_gettable
function discussed previously, these functions return the information
as a tabular result. The available functions are as follows:
fn_trace_getinfo(trace_id)— This function is passed a traceid, and it returns information about the specified trace. If passed the value of default, it returns information about all existing traces. An example of the output from this function is shown in Listing 2.
fn_trace_geteventinfo(trace_id)—
This function returns a list of the events and data columns being
captured for the specified trace. Only the event and column ID values
are returned. You can use the information provided in Tables 1 and 2 to map the IDs to the more meaningful event names and column names.
fn_trace_getfilterinfo(trace_id)—
This function returns information about the filters being applied to
the specified trace. Again, the column ID and logical and comparison
operator values are returned as integer IDs that you need to decipher.
See Table 3 for a listing of the column operator values.
Listing 2. An Example of Using the Built-in User-Defined Functions for Monitoring Traces
SELECT * FROM ::fn_trace_getinfo(default)
traceid property value ---------------------------------------------------------------------- 1 1 2 1 2 C:\Program Files\Microsoft SQL Server\MSSQL.1\ MSSQL\LOG\log_376.trc 1 3 20 1 4 NULL 1 5 1 2 1 0 2 2 c:\trace\mytrace.trc.trc 2 3 5 2 4 NULL 2 5 1
select * from ::fn_Trace_getfilterinfo(2)
columnid logical_operator comparison_operator value ------------------------------------------------------------- 3 0 0 6 10 0 7 Profiler 10 0 7 SQLAgent
|
Note
You may be wondering why there is always a traceid with a value of 1 running when you run the fn_trace_getinfo
procedure. This is the default trace that SQL Server automatically
initiates when it starts. The default trace is enabled by default. You
can identify which trace is the default by selecting from the sys.traces catalog view and examining the is_default
column. The default trace captures a number of different types of
events, including object creates and drops, errors, memory and disk
changes, security changes, and more. You can disable this default trace,
but it is generally lightweight and should be left enabled.
The output from the
functions that return trace information is relatively cryptic because
many of the values returned are numeric. For example, the property
values returned by fn_trace_getinfo are specified as integer IDs. Table 6.5 describes of each of these property IDs.
Table 4. Description of Trace Property ID Values
Property ID | Description |
---|
1 | Trace options specified in sp_trace_create |
2 | Trace filename |
3 | Maximum size of trace file, in MB |
4 | Date and time the trace will be stopped |
5 | Current trace status |
Stopping Server-Side Traces
It
is important to keep track of the traces you have running and to ensure
that “heavy” traces are stopped. Heavy traces are typically traces that
capture a lot of events and are run on a busy SQL Server. These traces
can affect the overall performance of your SQL Server machine and write a
large amount of information to the trace output file. If you specified a
stop time when you started the trace, it automatically stops and closes
when the stop time is reached. For example, in the SQL script in Listing 6.2, if you wanted the trace to run for 15 minutes instead of indefinitely, you would set the value for the stoptime variable at the beginning of the script, using a command similar to the following:
set @stoptime = dateadd(minute, 15, getdate())
To otherwise stop a running server-side trace, you use the sp_trace_setstatus stored procedure and pass it the trace ID and a status of 0.
Stopping a trace only stops gathering trace information and does not
delete the trace definition from SQL Server. Essentially, it pauses the
trace. You can restart the trace by passing sp_trace_setstatus a status value of 1.
After you stop a trace, you can close the trace and delete its definition from SQL Server by passing sp_trace_setstatus the ID of the trace you want to stop and a status value of 2. After you close the trace, you must redefine it before you can restart it.
If you don’t know the ID of the trace you want to stop, you can use the fn_trace_getinfo function or the sys.traces
catalog view to return a list of all running traces and select the
appropriate trace ID. The following example shows how to stop and close a
trace with a trace ID of 2:
-- Set the trace status to stop
exec sp_trace_setstatus 2, 0
go
-- Close and Delete the trace
exec sp_trace_setstatus 2, 2
go
If you want to stop and close multiple traces, you must call sp_trace_setstatus twice for each trace. Listing 3
provides an example of a system stored procedure that you can create in
SQL Server to stop a specific trace or automatically stop all currently
running traces.
Listing 3. A Sample System Stored Procedure to Stop Profiler Traces
use master go if object_id ('sp_stop_profiler_trace') is not null drop proc sp_stop_profiler_trace go
create proc sp_stop_profiler_trace @TraceID int = null as
if @TraceID is not null begin -- Set the trace status to stop exec sp_trace_setstatus @TraceID, 0
-- Delete the trace exec sp_trace_setstatus @TraceID, 2 end else begin -- the following cursor does not include the default trace declare c1 cursor for SELECT distinct traceid FROM :: fn_trace_getinfo (DEFAULT) WHERE traceId not in (select ID from sys.traces where is_default = 1) open c1 fetch c1 into @TraceID while @@fetch_status = 0 begin -- Set the trace status to stop exec sp_trace_setstatus @TraceID, 0
-- Delete the trace exec sp_trace_setstatus @TraceID, 2 fetch c1 into @TraceID end close c1 deallocate c1 end
|